#ifndef _WMI_RESULT_H
#define _WMI_RESULT_H

/******************************************************************************
** @file	wmi_result.h
** @author  Andrea Herbas
**
** @date	Jul 22, 2010
**
** @desc	This class represents the result of a query execution. It 
**          formats and builds WinObjects. Finnally, represents the result
**          in a vector.
**          			
**
******************************************************************************/

#include <iostream>
#include <comdef.h>
#include <Wbemidl.h>
#include <vector>
#pragma comment(lib, "wbemuuid.lib")
#include "wmi_share.h"
#include "wmi_process.h"
#include "wmi_iwinobject.h"

using namespace std;


template <typename T>
class WMI_Result
{
public:
    /**
    * Class constructor.
    *
    * @param pe enumerator that will provide the data
    * for fill the vector with win objects.
    */
    WMI_Result()
    {
		
    }

    /**
    * Class destructor
    */
    ~WMI_Result()
    {
        for(vector<T*>::iterator it = _objects.begin(); it != _objects.end(); it++)
        {
            delete *it;
        }
    }

    /**
    * Iterates over the Enumerator to obtain each element of 
    * the resultant query. Each of them must be formatted and
    * inserted into a vector.
    */
    void 
    fillVector(IEnumWbemClassObject* pEnum)
    {
        IWbemClassObject *pclsObj = NULL;
        ULONG uReturn = 0;
        HRESULT hr;		

        while (pEnum)
        {
            hr = pEnum->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);

            if(0 == uReturn)
            {
                break;
            }

            T* obj = new T(pclsObj);
            _objects.push_back(obj);
        }

        if(pclsObj != 0)
        {
            pclsObj->Release();
        }
    }

    /**
    * Iterates over the vector and display the data of each of the elements.
    */
    void 
    showObjects()
    {
        for(vector<T*>::iterator it = _objects.begin(); it != _objects.end(); it++)
        {
            (*it)->print();
        }
    }
    
    /**
    * Return a reference to the resultant objects.
    *
    * @return a vector of the resultant objects.
    */
    vector<T*>& 
    getObjects()
    {
        return _objects;
    }

private:
    /**
    * Vector of results
    */
    vector<T*> _objects;
};

/**
* WMI_Registry specialization
*/
#include "wmi_registry.h"
using namespace log4cxx;
using namespace log4cxx::xml;
using namespace log4cxx::helpers;
template <>
class WMI_Result<WMI_Registry>
{
public:
    /**
    * Class constructor.
    *
    * @param pe enumerator that will provide the data
    * for fill the vector with win objects.
    */
    WMI_Result()
    {
		
    }

    /**
    * Copy constructor.
    */
	WMI_Result(const WMI_Result& other)
	{
		this->rclass = other.rclass;
		
	}

    /**
    * Class destructor
    */
    ~WMI_Result()
    {

    }

    /**
    * Iterates over the vector and display the data of each of the elements.
    */
    void 
    showObjects()
    {
		rclass->print();
    }
    
    /**
    * Return a reference to the resultant objects.
    *
    * @return a vector of the resultant objects.
    */
    vector<WMI_Registry*>&
    getObjects()
    {
		return rclass->getRegistryList();
    }

    /**
    * Set a reference to the resultant objects.
    *
    * @return a vector of the resultant objects.
    */
	void setWRegistry(WMI_Registry* rclass)
	{
		this->rclass = rclass;
	}

private:

    /**
    * Holds a pointer to a WMI_Registry object.
    */
	WMI_Registry* rclass;
};

#include "wmi_filedirectory.h"
#include "WMI_Directory.h"
#include <vector>
#include <string>
#include <comdef.h>
#include <Wbemidl.h>
using namespace std;
using namespace log4cxx;
using namespace log4cxx::xml;
using namespace log4cxx::helpers;

template <> 
class WMI_Result<WMI_FileDirectory>
{ 

public:
    /**
    * Class constructor.
    */
    WMI_Result()
    {
       
    }

    /**
    * Class destructor
    */
    ~WMI_Result()
    {        
    }

    /**
    * Sets the parent directory name.
    *
    * @param a string that represents the directory name
    */
    void
    setParent(wstring& dirName)
    {
        _objects = new WMI_Directory(dirName);
    }

    /**
    * Iterates over the Enumerator to obtain each element of 
    * the resultant query. Each of them must be formatted and
    * inserted into a composite structure.
    *
    * @param an enumumerator used to fill the WMI_FileDirectory's
    *        properties.
    */
    void 
    fillVector(IEnumWbemClassObject* pEnum)
    {
        IWbemClassObject *pclsObj = NULL;
        ULONG uReturn = 0;
        HRESULT hr;		

        while (pEnum)
        {
            hr = pEnum->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);

            if(0 == uReturn)
            {
                break;
            }

            WMI_FileDirectory* obj = new WMI_FileDirectory(pclsObj);
            _objects->addFileDir(obj);
        }

        if(pclsObj != 0)
        {
            pclsObj->Release();
        }
    }

    /**
    * Moves over a composite structure and display the data of each of the elements.
    */
    void 
    showObjects()
    {
        _objects->print();
    }
    
    /**
    * Return a reference to the resultant objects.
    *
    * @return the objects ordered in a jerarquy.
    */
    WMI_Directory* 
    getObjects()
    {
        return _objects;   
    }

private:
    /**
    * Vector of directory results
    */
    WMI_Directory* _objects;
};


#endif